using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.IO;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Diagnostics;
using System.Windows.Forms;
using System.Data;
using System.Globalization;

namespace SCPutils
{

    /// <summary>
    /// Class containing static methods which are usefull for different common tasks 
    /// </summary>
    public class Utils
    {
        /// <summary>
        /// Object used for combobox items
        /// </summary>
        public class ComboItem : object
        {
            /// <summary>
            /// text
            /// </summary>
            protected String m_Name;
            /// <summary>
            /// text
            /// </summary>
            protected String m_Value;
            /// <summary>
            /// text
            /// </summary>
            public ComboItem() { }
            /// <summary>
            /// text
            /// </summary>
            public ComboItem(String name, String value)
            {
                m_Name = name;
                m_Value = value;
            }
            /// <summary>
            /// text
            /// </summary>
            public override string ToString()
            {
                return m_Name;
            }
            /// <summary>
            /// text
            /// </summary>
            public int getKey()
            {
                return int.Parse(m_Value);
            }
            /// <summary>
            /// text
            /// </summary>
            public String getName()
            {
                return m_Name;
            }
        };
        /// <summary>
        /// text
        /// </summary>
        public class Data
        {   
            /// <summary>
            /// text
            /// </summary>
            public static DataTable GetDataTableFromDGV(DataGridView dgv)
            {
                var dt = new DataTable();
                foreach (DataGridViewColumn column in dgv.Columns)
                {
                    if (column.Visible)
                    {
                        // You could potentially name the column based on the DGV column name (beware of dupes)
                        // or assign a type based on the data type of the data bound to this DGV column.
                        dt.Columns.Add(new DataColumn(column.Name));
                    }
                }

                object[] cellValues = new object[dgv.Columns.Count];
                foreach (DataGridViewRow row in dgv.Rows)
                {
                    for (int i = 0; i < row.Cells.Count; i++)
                    {
                        cellValues[i] = row.Cells[i].Value;
                    }
                    dt.Rows.Add(cellValues);
                }

                return dt;
            }

            /// <summary>
            /// text
            /// </summary>
            public static String _sql(String strInput)
            {
                if (strInput == null) return null;
                return strInput.Replace("'", "''");
            }
        };

        /// <summary>
        /// text
        /// </summary>
        public class Security
        {
            /// <summary>
            /// text
            /// </summary>
            public static string _encode(string strInput)
            {
                strInput = "cicipoc" + strInput + "SimplePenaltyCalculator";
                byte[] pass = Encoding.UTF8.GetBytes(strInput);
                MD5 md5 = new MD5CryptoServiceProvider();
                return Convert.ToBase64String(md5.ComputeHash(pass));
            }

            /// <summary>
            /// text
            /// </summary>
            public static string getIdentifier(string wmiClass, string wmiProperty)
            //Return a hardware identifier
            {
                string result = "";
                System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass);
                System.Management.ManagementObjectCollection moc = mc.GetInstances();
                foreach (System.Management.ManagementObject mo in moc)
                {
                    //Only get the first one
                    if (result == "")
                    {
                        try
                        {
                            result = mo[wmiProperty].ToString();
                            break;
                        }
                        catch
                        {
                        }
                    }
                }
                return result.Replace(" ", string.Empty);

                //string modelNo = Utils.Security.getIdentifier("Win32_DiskDrive", "Model");
                //string manufatureID = Utils.Security.getIdentifier("Win32_DiskDrive", "Manufacturer");
                //string signature = Utils.Security.getIdentifier("Win32_DiskDrive", "Signature");
                //string totalHeads = Utils.Security.getIdentifier("Win32_DiskDrive", "TotalHeads");
            }

        }

        /// <summary>
        /// text
        /// </summary>
        public class Unix
        {
            /// <summary>
            /// text
            /// </summary>
            private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

            /// <summary>
            /// text
            /// </summary>
            public static long GetCurrentUnixTimestampMillis()
            {
                return (long)(DateTime.UtcNow - UnixEpoch).TotalMilliseconds;
            }

            /// <summary>
            /// text
            /// </summary>
            public static DateTime DateTimeFromUnixTimestampMillis(long millis)
            {
                return UnixEpoch.AddMilliseconds(millis);
            }
            /// <summary>
            /// text
            /// </summary>
            public static long GetCurrentUnixTimestampSeconds()
            {
                return (long)(DateTime.UtcNow - UnixEpoch).TotalSeconds;
            }
            /// <summary>
            /// text
            /// </summary>
            public static long GetUnixTimestampSecondsFromMonthYear(string strMonthYear)
            {
                string format = "MM.yyyy";
                CultureInfo provider = CultureInfo.InvariantCulture;
                try
                {
                    DateTime result = DateTime.ParseExact(strMonthYear, format, provider);

                    result = result.AddHours(12);

                    return (long)(result - UnixEpoch).TotalSeconds;
                }
                catch (System.FormatException formatEx)
                {
                    return -1;
                }

            }
            /// <summary>
            /// text
            /// </summary>
            public static long GetUnixTimestampSecondsFromDateTime(DateTime objDateTime)
            {
                return (long)(objDateTime - UnixEpoch).TotalSeconds;
            }
            /// <summary>
            /// text
            /// </summary>
            public static DateTime DateTimeFromUnixTimestampSeconds(long seconds)
            {
                return UnixEpoch.AddSeconds(seconds);
            }
            /// <summary>
            /// text
            /// </summary>
            public static long GetUnixTimestampSecondsFromCurrentMonth()
            {
                DateTime currentMonth = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1, 12, 0, 0);
                return GetUnixTimestampSecondsFromDateTime(currentMonth);
            }
            /// <summary>
            /// text
            /// </summary>
            public static string GetMonthYearFormatFromCurrentMonth()
            {
                DateTime currentMonth = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1, 12, 0, 0);
                return currentMonth.ToString("MM/yyyy");
            }
            /// <summary>
            /// text
            /// </summary>
            public static DateTime GetDateTime_BeginningOfMonth(DateTime dateTime)
            {
                return new DateTime(dateTime.Year, dateTime.Month, 1, 12, 0, 0);
            }
        };


        /// <summary>
        /// Gets the current application path
        /// </summary>
        public static string appPath = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
        /// <summary>
        /// Stores the mimeType disctionary entity
        /// </summary>
        public static csvDictionary mimeTypes = new csvDictionary(System.IO.Path.GetDirectoryName(Application.ExecutablePath) + "\\mimeTypes.csv");
        /// <summary>
        /// 
        /// Stores the full path to the CHM help file
        /// </summary>
        public static string helpFile = "";
        /// <summary>
        /// Calculates and returns the MD5 hash for the incoming string
        /// </summary>
        /// <param name="strInput"></param>
        /// <returns></returns>
        public static string calculateMD5(string strInput)
        {
            HashAlgorithm hash = HashAlgorithm.Create("MD5");
            byte[] arrHash = hash.ComputeHash(Encoding.ASCII.GetBytes(strInput));

            StringBuilder md5Hash = new StringBuilder();
            for (int i = 0; i < arrHash.Length; i++)
            {
                md5Hash.Append(arrHash[i].ToString("X2"));
            }
            return md5Hash.ToString();
        }

        /// <summary>
        /// Calculates and returns the MD5 hash for the incoming byte collection
        /// </summary>
        /// <param name="arrInput"></param>
        /// <returns></returns>
        public static string calculateMD5(byte[] arrInput)
        {
            HashAlgorithm hash = HashAlgorithm.Create("MD5");
            byte[] arrHash = hash.ComputeHash(arrInput);

            StringBuilder md5Hash = new StringBuilder();
            for (int i = 0; i < arrHash.Length; i++)
            {
                md5Hash.Append(arrHash[i].ToString("X2"));
            }
            return md5Hash.ToString();
        }

        /// <summary>
        /// Stores the parent MDI form
        /// </summary>
        public static System.Windows.Forms.Form parentMdiForm = null;

        /// <summary>
        /// Private property for storing the base of the Unix timestamp
        /// </summary>
        private static readonly DateTime UnixBase = new DateTime( 1970, 1, 1 );

        /// <summary>
        /// Stores the defined language for current user
        /// </summary>
        static private string lang = "EN";
        /// <summary>
        /// Gets an embedded resource  from SCPutils resource file
        /// </summary>
        /// <param name="resource"></param>
        /// <returns></returns>
        static public Stream getEmbeddedResource(string resource)
        {
            Assembly assem = System.Reflection.Assembly.GetExecutingAssembly();

            Stream resStream = assem.GetManifestResourceStream("SCPutils." + resource);

            if (resStream == null)
                throw new Exception("Internal resource not found : " + resource);

            return resStream;
        }
        /// <summary>
        /// Converts the .Net DateTime value to Unix timestamp
        /// </summary>
        /// <param name="dotNetValue">DateTime value</param>
        /// <returns>Unix timestamp - number of second from 1 January 1970</returns>
        static public uint dotNetToUnix(DateTime dotNetValue)
        {
            return (uint) dotNetValue.Subtract(Utils.UnixBase).TotalSeconds;
        }

        /// <summary>
        /// Converts the  Unix timestamp to .Net DateTime value
        /// </summary>
        /// <param name="timestampValue">Unix timestamp</param>
        /// <returns>DateTime entity</returns>
        static public DateTime unixToDotNet(uint timestampValue)
        {
            return (Utils.UnixBase.AddSeconds(timestampValue));
        }


        /// <summary>
        /// Removes any HTML tag from the incoming text
        /// </summary>
        /// <param name="strIncoming"></param>
        /// <returns></returns>
        static public string stripHTML(string strIncoming)
        {
            string pattern = @"<(.|\n)*?>";

            return Regex.Replace(strIncoming, pattern, string.Empty);
        }
        /// <summary>
        /// Gets and Sets the language for the current user
        /// </summary>
        static public string language
        {
            set { Utils.lang = value; }
            get { return Utils.lang.ToUpper(); }
        }
        /// <summary>
        /// Decodes incoming XML string by replacing encoded special characters with the correct ones
        /// </summary>
        /// <param name="strText"></param>
        /// <returns></returns>
        static public string decodeXML(string strText)
        {
            List<string> listChar = new List<string>();
            List<string> listCharEncoded = new List<string>();
            listChar.Add ("&");
            listCharEncoded.Add("&amp;");
            listChar.Add ("<");
            listCharEncoded.Add("&lt;");
            listChar.Add (">");
            listCharEncoded.Add("&gt;");
            listChar.Add ("\"");
            listCharEncoded.Add("&quot;");
            listChar.Add ("'");
            listCharEncoded.Add("&apos;");

            for (int i=0; i<listChar.Count ; i++) {
                strText = strText.Replace(listCharEncoded[i], listChar[i]);
            }

            return strText;
        }
        /// <summary>
        /// Cleans the incoming file name by removing any special or not allowed character and replacint it with underscore '_'
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        static public string cleanFileName(string fileName)
        {
            return Regex.Replace(fileName, @"[?:\/*""<>|]", "_");
        }

       
    }
    /// <summary>
    /// Defines the Shel file info structure
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct SHFILEINFO
    {
        /// <summary>
        /// Handle to the icon that represents the file
        /// </summary>
        public IntPtr hIcon;
        /// <summary>
        /// Index of the icon image within the system image list
        /// </summary>
        public IntPtr iIcon;
        /// <summary>
        /// Array of values that indicates the attributes of the file object
        /// </summary>
        public uint dwAttributes;
        /// <summary>
        /// String that contains the name of the file as it appears in the Microsoft Windows Shell, or the path and file name of the file that contains the icon representing the file.
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string szDisplayName;
        /// <summary>
        /// String that describes the type of file.
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
        public string szTypeName;
    };

    /// <summary>
    /// Class for executing calls to Win32 functions
    /// </summary>
    public class Win32
    {
        /// <summary>
        /// Retrieve the handle to the icon that represents the file and the index of the icon within the system image list. The handle is copied to the hIcon member of the structure specified by psfi, and the index is copied to the iIcon member
        /// </summary>
        public const uint SHGFI_ICON = 0x100;
        /// <summary>
        /// Modify SHGFI_ICON, causing the function to retrieve the file's large icon. The SHGFI_ICON flag must also be set
        /// </summary>
        public const uint SHGFI_LARGEICON = 0x0;    // 'Large icon
        /// <summary>
        /// Modify SHGFI_ICON, causing the function to retrieve the file's small icon. 
        /// </summary>
        public const uint SHGFI_SMALLICON = 0x1;    // 'Small icon

        /// <summary>
        /// Imports the Win32 function which retrieves information about an object in the file system, such as a file, a folder, a directory, or a drive root.
        /// </summary>
        /// <param name="pszPath"></param>
        /// <param name="dwFileAttributes"></param>
        /// <param name="psfi"></param>
        /// <param name="cbSizeFileInfo"></param>
        /// <param name="uFlags"></param>
        /// <returns></returns>
        [DllImport("shell32.dll")]
        public static extern IntPtr SHGetFileInfo(string pszPath,
                                    uint dwFileAttributes,
                                    ref SHFILEINFO psfi,
                                    uint cbSizeFileInfo,
                                    uint uFlags);
    }

}
